<template>
  <div class="body" v-loading="loading">
    <div>
      <template v-if="header.status === 'audit'">
        <el-button type="warning" size="small" icon="el-icon-s-promotion" @click="doUnAudit">&nbsp;反&nbsp;审&nbsp;</el-button>
      </template>
      <template v-else-if="header.status === 'save'">
        <el-button type="primary" size="small" icon="el-icon-check" @click="doSave">&nbsp;保&nbsp;存&nbsp;</el-button>
        <el-button type="primary" size="small" icon="el-icon-s-promotion" @click="doAudit">&nbsp;审&nbsp;核&nbsp;</el-button>
        <el-button type="success" size="small" icon="el-icon-refresh" @click="getOrder(header.orderNo, true)">&nbsp;恢&nbsp;复&nbsp;</el-button>
        <el-button type="danger" size="small" icon="el-icon-delete" @click="doDelete">&nbsp;删&nbsp;除&nbsp;</el-button>
      </template>
      <el-button type="info" size="small" icon="el-icon-back" @click="doBack">&nbsp;返&nbsp;回&nbsp;</el-button>
    </div>
    <el-form :model="header" size="small" label-width="80px" :inline="true" class="header">
      <div class="audit_icon iconfont icon-yishenhe" v-if="header.status === 'audit'"></div>
      <el-row>
        <el-col :span="6"><el-form-item label="单据编号">{{ header.orderNo }}</el-form-item></el-col>
        <el-col :span="6"><el-form-item label="单据类型">{{ orderTypeMap[header.orderType] || header.orderType }}</el-form-item></el-col>
        <el-col :span="12"><el-form-item label="合同编号">{{ header.billNo }}</el-form-item></el-col>
      </el-row>
      <el-row>
        <el-col :span="6">
          <el-form-item label="采购日期" class="header_must">
            <span v-if="header.status === 'audit'">{{ dayjs(header.purchaseDate).format('YYYY-MM-DD') }}</span>
            <el-date-picker v-else size="small" v-model="header.purchaseDate" clearable style="width: 150px;" />
          </el-form-item>
        </el-col>
        <el-col :span="6"><el-form-item label="采购部门">{{ header.purchaseDeptName }}</el-form-item></el-col>
        <el-col :span="6"><el-form-item label="采购员">{{ header.purchaserName }}</el-form-item></el-col>
      </el-row>
      <el-row>
        <el-col :span="6"><el-form-item label="供应商">{{ header.supplierName }}</el-form-item></el-col>
        <el-col :span="6"><el-form-item label="结算方">{{ header.settle }}</el-form-item></el-col>
        <el-col :span="6"><el-form-item label="收款方">{{ header.charge }}</el-form-item></el-col>
      </el-row>
      <el-row>
        <el-col :span="24"><el-form-item label="备注">{{ header.remark }}</el-form-item></el-col>
      </el-row>
      <br />
    </el-form>
    <div v-if="header.status === 'save'">
        <el-button type="danger" size="small" icon="el-icon-delete" @click="deleteMaterialDetails">删除选择行</el-button>
        <el-button type="primary" size="small" icon="el-icon-plus" @click="addMaterialDetail">添加分录行</el-button>
    </div>
    <el-table :data="dataList" class="detail" height="calc(100vh - 370px)" @selection-change="selectMaterials">
      <el-table-column label="#" width="60" align="center" type="selection" v-if="header.status !== 'audit'"></el-table-column>
      <el-table-column label="No." width="60" align="right" type="index"></el-table-column>
      <el-table-column min-width="160" prop="materialNo">
        <template #header><span class="list_must">物料编码</span></template>
        <template #default="scope" v-if="header.status !== 'audit'">
          <el-select v-model="scope.row.materialNo" size="small" filterable remote :remote-method="e => getMaterialList(e)" @change="setMaterialValue(scope.row, materialList)" clearable placeholder="输入编码或名称">
            <el-option
                    v-for="item in materialList"
                    :key="item.fNumber"
                    :label="item.fNumber + ':' + item.fName + item.fSpecification"
                    :value="item.fNumber">
            </el-option>
          </el-select>
        </template>
      </el-table-column>
      <el-table-column label="物料名称(规格)" min-width="400">
        <template #default="scope"><span style="white-space: nowrap">{{ (scope.row.materialName || '') + ' ' + (scope.row.materialSpec || '') }}</span></template>
      </el-table-column>
      <el-table-column label="批次号" min-width="180" prop="batchNo">
        <template #default="scope" v-if="header.status !== 'audit'">
          <el-input type="text" size="small" v-model="scope.row.batchNo" />
        </template>
      </el-table-column>
      <el-table-column label="采购单位" min-width="80" prop="purchaseUnitName" align="center"></el-table-column>
      <el-table-column width="90" prop="qty" align="right">
        <template #header><span class="list_must">采购数量</span></template>
        <template #default="scope" v-if="header.status !== 'audit'">
          <el-input-number size="small" v-model="scope.row.qty" @change="updateRow(scope.row)" :controls="false" style="width: 100%" />
        </template>
      </el-table-column>
      <el-table-column label="计价单位" width="80" prop="calcUnitName" align="center"></el-table-column>
      <el-table-column width="150" prop="deliveryDate" align="center">
        <template #header><span class="list_must">交货日期</span></template>
        <template #default="scope" v-if="header.status !== 'audit'">
          <el-date-picker size="small" v-model="scope.row.deliveryDate" clearable style="width: 100%;" value-format="YYYY-MM-DD" />
        </template>
      </el-table-column>
      <el-table-column width="90" prop="price" align="right">
        <template #header><span class="list_must">单价</span></template>
        <template #default="scope" v-if="header.status !== 'audit'">
          <el-input-number size="small" v-model="scope.row.price" @change="updateRow(scope.row)" :controls="false" style="width: 100%" />
        </template>
      </el-table-column>
      <el-table-column label="含税单价" width="80" prop="taxPrice" align="right"></el-table-column>
      <el-table-column label="折扣率(%)" width="90" prop="discountRate" align="center">
        <template #default="scope" v-if="header.status !== 'audit'">
          <el-input-number size="small" v-model="scope.row.discountRate" @change="updateRow(scope.row)" :controls="false" style="width: 100%" />
        </template>
      </el-table-column>
      <el-table-column label="金额" width="120" prop="amount" align="right"></el-table-column>
      <el-table-column label="税率" width="120" prop="taxRateStr" align="center"></el-table-column>
      <el-table-column label="税额" width="80" prop="tax" align="right"></el-table-column>
      <el-table-column label="价税合计" width="150" prop="taxAmount" align="right"></el-table-column>
      <el-table-column label="是否赠品" size="small" width="110" prop="isGift" align="center">
        <template #default="scope" v-if="header.status === 'audit'">
          {{ scope.row.isGift === '1'? '是': '否' }}
        </template>
        <template #default="scope" v-else>
          <el-select v-model="scope.row.isGift" placeholder=" " size="small" clearable>
            <el-option key="0" value="0" label="否"></el-option>
            <el-option key="1" value="1" label="是"></el-option>
          </el-select>
        </template>
      </el-table-column>
      <el-table-column label="到货数量"  width="120" align="right" prop="settlementQty"></el-table-column>
      <el-table-column label="结算金额" width="120" align="right" prop="settlementAmount"></el-table-column>
      <el-table-column label="结算次数" width="120" align="right" prop="settlementCount"></el-table-column>
      <el-table-column label="操作" width="70" fixed="right" align="center">
        <template #default="scope">
          <el-button size="small" type="text" style="color: var(--el-color-info)" icon="el-icon-wallet" @click="viewSettlement(scope.row)" v-if="header.status === 'audit'">结算</el-button>
          <el-button size="small" type="text" style="color: var(--el-color-danger)" icon="el-icon-delete" v-else @click="deleteMaterialDetail(scope.row, scope.$index)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
    <el-drawer :title="`[ ${ header.orderNo } ] ${ selectedData.materialName || '' } ${selectedData.materialSpec || ''} 结算明细`" class="settlement" v-model="showSettlementDetail" direction="rtl" size="50%">
      <div class="settlement" v-loading="settlementLoading">
        <div>
          <el-button type="danger" size="small" icon="el-icon-delete" @click="doDeleteSettlements">删除选择行</el-button>
          <el-button type="primary" size="small" icon="el-icon-plus" @click="doAddSettlement">添加分录行</el-button>
        </div>
        <el-table :data="settlementList" class="detail_list" height="calc(100vh - 140px)" @selection-change="selectSettlements">
          <el-table-column label="#" width="60" align="center" type="selection" :selectable="isSettlementSelectable"></el-table-column>
          <el-table-column width="120" prop="settlementQty" align="right">
            <template #header><span class="list_must">结算数量</span></template>
            <template #default="scope">
              <template v-if="scope.row.status === 'audit'">{{ scope.row.settlementQty }}</template>
              <template v-else>
                <el-input-number size="small" v-model="scope.row.settlementQty" :controls="false" style="width: 100%" />
              </template>
            </template>
          </el-table-column>
          <el-table-column width="120" align="right">
            <template #header><span class="list_must">结算金额</span></template>
            <template #default="scope">
              <template v-if="scope.row.status === 'audit'">{{ scope.row.settlementAmount }}</template>
              <template v-else>
                <el-input-number size="small" v-model="scope.row.settlementAmount" :controls="false" style="width: 100%" />
              </template>
            </template>
          </el-table-column>
          <el-table-column label="创建时间" min-width="120" align="center">
            <template #default="scope">{{ scope.row.createTime? dayjs(scope.row.createTime).format('YYYY-MM-DD HH:mm'): '' }}</template>
          </el-table-column>
          <el-table-column label="创建人" width="100" prop="createUserName"></el-table-column>
          <el-table-column label="审核时间" min-width="120" align="center">
            <template #default="scope">{{ scope.row.auditTime? dayjs(scope.row.auditTime).format('YYYY-MM-DD HH:mm'): '' }}</template>
          </el-table-column>
          <el-table-column label="审核人" prop="auditUserName"></el-table-column>
          <el-table-column label="操作" width="120" align="left" fixed="right">
            <template #default="scope">
              <el-button type="text" size="small" style="color: var(--el-color-warning)" icon="el-icon-s-promotion" @click="doUnAuditSettlement(scope.row)" v-if="scope.row.status === 'audit'">反审</el-button>
              <el-button type="text" size="small" style="color: var(--el-color-primary)" icon="el-icon-check" @click="doSaveSettlement(scope.row)" v-if="scope.row.status !== 'audit'">保存</el-button>
              <el-button type="text" size="small" style="color: var(--el-color-success)" icon="el-icon-s-promotion" @click="doAuditSettlement(scope.row)" v-if="scope.row.status !== 'audit'">审核</el-button>
            </template>
          </el-table-column>
        </el-table>
      </div>
    </el-drawer>
  </div>
</template>
<script setup>
import dayjs from 'dayjs'
import { getCurrentInstance, ref, onMounted } from 'vue'
const { proxy } = getCurrentInstance()
const loading = ref(false)
const materialLoading = ref(false)
const settlementLoading = ref(false)
const materialList = ref([])
const header = ref({})
const dataList = ref([])
const dataSelection = ref([])
const selectedData = ref({})
const settlementList = ref([])
const settlementSelection = ref([])
const showSettlementDetail = ref(false)
const orderTypeMap = ref({})

onMounted(() => {
  let orderNo = proxy.$route.query.orderNo
  getDictionary()
  if (orderNo) {
    return getOrder(orderNo)
  }
})

/**
 * 获取字典
 */
const getDictionary = async () => {
  try {
    let res = await proxy.$api.getChildDictionaryListByKeys({ keys: ['orderType'] })
    if (!res.res) return
    let list = res.orderType || []
    let _orderTypeMap = {}
    for(let i = 0; i < list.length; i++) {
      _orderTypeMap[ list[i].key ] = list[i].name
    }
    orderTypeMap.value = _orderTypeMap
  } finally {
  }
}

/**
 * 获取物料数据
 */
const getMaterialList = async val => {
  if (!val) {
    materialList.value = []
    return
  }
  materialLoading.value = true
  try {
    const res = await proxy.callApi('get_material_list', { key: val, pageSize: 20 })
    if (!res.res) return
    materialList.value = res.data
  } finally {
    materialLoading.value = false
  }
}
/**
 * 设置物料行
 */
const setMaterialValue = (row, materialList) => {
  if (row.materialNo) {
    for(let i = 0; i < materialList.length; i++) {
      let m = materialList[i]
      if (m.fNumber === row.materialNo) {
        Object.assign(row, {
          materialNo: m.fNumber,
          materialName: m.fName,
          materialSpec: m.fSpecification,
          taxRateStr: m.FEntryTaxRate,
          taxRate: m.FEntryTaxRate.match(/(\S*)%/)[1] * 0.01,
          purchaseUnitName: m.fBaseUnitIdFName,
          calcUnitName: m.fBaseUnitIdFName
        })
        updateRow(row)
        break
      }
    }
  }
}

/**
 * 返回
 */
const doBack = () => {
  return proxy.$router.push('/purchase/purOrderList')
}

/**
 * 保存订单
 */
const doSave = async () => {
  if (!header.value.purchaseDate) {
    proxy.$message.error('请输入采购日期!')
    return
  }
  if (dataList.value.length === 0) {
    this.$message.error('请添加分录!')
    return
  }
  for(let i = 0; i < dataList.value.length; i++) {
    let data = dataList.value[i]
    if (!data.materialNo || !data.qty || !data.deliveryDate || !data.price) {
      proxy.$message.error(`分录行[${ i + 1 }]物料，采购数量，交货日期，单价都必填!`)
      return
    }
  }
  loading.value = true
  try {
    let param = {
      orderNo: header.value.orderNo,
      purchaseDate: dayjs(header.value.purchaseDate).format('YYYY-MM-DD'),
      dataList: dataList.value
    }
    let res = await proxy.callApi('save_pur_order', param)
    if (!res.res) return
    proxy.$message.success('保存完成!')
    return getOrder(header.value.orderNo)
  } finally {
    loading.value = false
  }
}

const doDelete = async () => {
  try {
    await proxy.$confirm('确定删除吗？', '提示', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    })
  } catch(e) {
    return
  }
  loading.value = true
  try {
    let res = await proxy.callApi('delete_pur_order', { orderNo: header.value.orderNo })
    if (!res.res)return
    return doBack()
  } finally {
    loading.value = false
  }
}

/**
 * 审核
 */
const doAudit = async () => {
  loading.value = true
  try {
    let res = await proxy.callApi('audit_pur_order', { orderNo: header.value.orderNo, billNo: header.value.billNo })
    if (!res.res) return
    header.value.status = 'audit'
    proxy.$message.success('审核完成!')
  } finally {
    loading.value = false
  }
}
/**
 * 反审核
 */
const doUnAudit = async () => {
  loading.value = true
  try {
    let res = await proxy.callApi('un_audit_pur_order', { orderNo: header.value.orderNo })
    if (!res.res) return
    header.value.status = 'save'
    proxy.$message.success('反审完成!')
  } finally {
    loading.value = false
  }
}

/**
 * 获取单据
 */
const getOrder = async (orderNo, reset) => {
  if (reset) {
    try {
      await proxy.$confirm('恢复后未保存数据将被清除，确定恢复吗？', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
    } catch(e) {
      return
    }
  }
  loading.value = true
  try {
    let res = await proxy.callApi('get_pur_order', { orderNo })
    if (!res.res) return
    header.value = Object.assign({ purchaseDate: dayjs().format('YYYY-MM-DD') }, res.header) || {}
    dataList.value = res.data || []
  } finally {
    loading.value = false
  }
}

/**
 * 添加分录行
 */
const addMaterialDetail = () => {
  dataList.value.push({
    billNo: header.value.billNo,
    orderNo: header.value.orderNo,
    isGift: '0',
    settlementQty: 0,
    settlementAmount: 0,
    settlementCount: 0 })
}

/**
 * 删除选中分录行
 */
const deleteMaterialDetails = async() => {
  if (dataSelection.value.length === 0) {
    proxy.$message.error('请选择分录行!')
    return
  }
  let hasSettlement = dataSelection.value.some(v => !!v.settlementCount)
  if (hasSettlement) {
    try {
      await this.$confirm('物料存在结算单据, 确定删除吗', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
    } catch (e) {
      return
    }
  } else {
    try {
      await proxy.$confirm('确定删除吗?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
    } catch (e) {
      return
    }
  }
  dataSelection.value.forEach(sel => {
    for (let i = 0; i < dataList.value.length; i++) {
      if (dataList.value[i] === sel) {
        dataList.value.splice(i, 1)
        break
      }
    }
  })
}

/**
 * 删除分录行
 */
const deleteMaterialDetail = async (row, i) => {
  if (row.settlementCount) {
    try {
      await proxy.$confirm('物料存在结算单据, 确定删除吗?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
    } catch (e) {
      return
    }
  } else {
    try {
      await proxy.$confirm('确定删除吗?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
    } catch (e) {
      return
    }
  }
  dataList.value.splice(i, 1)
}

/**
 * 物料行选择
 */
const selectMaterials = data => {
  dataSelection.value = data
}

/**
 * 行数据更新
 */
const updateRow = row => {
  // 数量
  let qty = row.qty || 0
  // 单价
  let price = row.price || 0
  // 折扣率
  let discountRate = (row.discountRate || 100) / 100
  // 税率
  let taxRate = row.taxRate || 0

  // 含税单价
  let taxPrice = (1 + taxRate) * price
  // 总价
  let amount = qty * price * discountRate
  // 含税总价
  let taxAmount = taxPrice * qty * discountRate

  // 含税单价
  row.taxPrice = Number(taxPrice.toFixed(2))
  // 总价
  row.amount = Number(amount.toFixed(2))
  // 含税总价
  row.taxAmount = Number(taxAmount.toFixed(2))
  // 税额
  row.tax = Number((taxAmount - amount).toFixed(2))
}

/**
 * 查看结算详细
 */
const viewSettlement = async material => {
  selectedData.value = material
  showSettlementDetail.value = true
  return getSettlement()
}

/**
 * 查看结算详细
 */
const getSettlement = async () => {
  settlementLoading.value = true
  try {
    let res = await proxy.callApi('get_pur_order_settlement', { detailId: selectedData.value.id })
    if (!res.res) return
    settlementList.value = res.data || []
  } finally {
    settlementLoading.value = false
  }
}

/**
 * 添加结算分录行
 */
const doAddSettlement = () => {
  settlementList.value.unshift({ settlementQty: 0, settlementAmount: 0 })
}

/**
 * 保存结算分录行
 */
const doSaveSettlement = async row => {
  if (!row.settlementQty) {
    proxy.$message.error('请输入结算数量!')
    return
  }
  settlementLoading.value = true
  try {
    let res = await proxy.callApi('save_pur_order_settlement', {
      billNo: header.value.billNo,
      orderNo: header.value.orderNo,
      detailId: selectedData.value.id,
      id: row.id,
      settlementQty: row.settlementQty,
      settlementAmount: row.settlementAmount
    })
    if (!res.res) return
    proxy.$message.success('保存完成!')
    return getSettlement()
  } finally {
    settlementLoading.value = false
  }
}

/**
 * 删除结算分录行
 */
const doDeleteSettlements = async() => {
  if (settlementSelection.value.length === 0) {
    proxy.$message.error('请选择分录行!')
    return
  }
  let ids = []
  settlementSelection.value.every(v => {
    if (v.id) ids.push(v.id)
  })
  try {
    await proxy.$confirm('确定删除吗?', '提示', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    })
  } catch (e) {
    return
  }
  if (ids.length > 0) {
    settlementLoading.value = true
    try {
      let res = await proxy.callApi('delete_pur_order_settlement', { ids })
      if (!res.res) return
    } finally {
      settlementLoading.value = false
    }
  }
  return getSettlement()
}

/**
 * 保存结算分录行
 */
const doAuditSettlement = async row => {
  settlementLoading.value = true
  try {
    let res = await proxy.callApi('audit_pur_order_settlement', { id: row.id })
    if (!res.res) return
    proxy.$message.success('审核完成!')
    getOrder(header.value.orderNo)
    return getSettlement()
  } finally {
    settlementLoading.value = false
  }
}

/**
 * 保存结算分录行
 */
const doUnAuditSettlement = async row => {
  settlementLoading.value = true
  try {
    let res = await proxy.callApi('un_audit_pur_order_settlement', { id: row.id })
    if (!res.res) return
    proxy.$message.success('反审完成!')
    getOrder(header.value.orderNo)
    return getSettlement()
  } finally {
    settlementLoading.value = false
  }
}

/**
 * 未审核行可选择，用于删除
 */
const isSettlementSelectable = row => {
  return row.status !== 'audit'
}

/**
 * 结算行选择
 */
const selectSettlements = data => {
  settlementSelection.value = data
}
</script>

<style lang="scss" scoped>
  .body {
    padding: 20px 0;
    .header {
      margin-top: 20px;
      position: relative;
      .header_row {
        display: flex;
        >div {
          flex-shrink: 0;
        }
        :deep(.produceDate) {
          .el-input {
            width: 100%!important;
          }
        }
      }
      .audit_icon {
        position: absolute;
        top: -10px;
        left: 60px;
        font-size: 48px;
        color: red;
      }
      .material {
        width: 100%;
      }
      .p3 {
        :deep(.el-form-item__content) {
          display: flex;
          .comment {
            margin-left: 10px;
            word-break: keep-all;
          }
        }
      }
    }
  }
  .settlement {
    margin: 0 20px 20px;
    .detail_list {
      margin-top: 10px;
    }
  }
  :deep(.header_must) {
    >label {
      &:before {
        content: '*';
        color: var(--el-color-danger);
      }
    }
  }
  .list_must {
    &:before {
      content: '*';
      color: var(--el-color-danger);
    }
  }
</style>
